﻿/*
 * Created by SharpDevelop.
 * User: Matjaž
 * Date: 29.12.2008
 * Time: 14:03
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace gopher
{
	/// <summary>
	/// Description of Ask.
	/// </summary>
	public partial class Ask : Form
	{
		public string mojStreznik;
		public string mojSelektor;
		public string mojaVrata;
		public int mojTimeout;
		public List<string> askStrings = new List<string>();
		public List<String> rezultat = new List<string>();
		public Ask(string selektor, string streznik, string vrata, int iTimeout)
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			mojStreznik = streznik;
			mojSelektor = selektor;
			mojaVrata = vrata;
			mojTimeout = iTimeout;
		}
		
		static string ReadLine (Stream s)
		{
			List<byte> lineBuffer = new List<byte>();
			while (true)
			{
				int b = s.ReadByte();
				if (b == 10 || b < 0) break;
				if (b != 13) lineBuffer.Add ((byte)b);
			}
			return Encoding.UTF8.GetString (lineBuffer.ToArray());
			//return Encoding.ASCII.GetString (lineBuffer.ToArray());
		}
		
		static void SendCommand (Stream stream, string line)
		{
			byte[] data = Encoding.UTF8.GetBytes (line + "\r\n");
			//byte[] data = Encoding.ASCII.GetBytes (line + "\r\n");
			stream.Write (data, 0, data.Length);
		}
		
		static void SendResponse (Stream stream, byte[] data)
		{
			//byte[] data = Encoding.UTF8.GetBytes (line + "\r\n");
			//byte[] data = Encoding.ASCII.GetBytes (line + "\r\n");
			stream.Write (data, 0, data.Length);
		}
		
		void AskLoad(object sender, EventArgs e)
		{
			List<string> vrstice = new List<string>();
			if(askStrings.Count == 0)
			{
				using (TcpClient client = new TcpClient (mojStreznik, Convert.ToInt32(mojaVrata)))
				using (NetworkStream n = client.GetStream())
				{
					//MessageBox.Show(mojSelektor);
					SendCommand(n, mojSelektor+"\t!");
					
					//List<string> imenik = new List<string>();
					
					StringBuilder SB = new StringBuilder();

					int j = 0;
					while(vrstice.Count == 0)		//
					{								// večkratna ponovitev če večkrat ne dobimo nič...
						j++;
						if (n.DataAvailable == false) Thread.Sleep(mojTimeout);
						this.Cursor = Cursors.WaitCursor;
						//int i = 0;
						while (n.DataAvailable)
						{
							string line = ReadLine (n);
							vrstice.Add(line);

							if (n.DataAvailable == false) Thread.Sleep(mojTimeout);
						}
						if((j == 50) || (vrstice.Count != 0))					// poskusimo petkrat
						{							// to je za to, da nimamo večkratnik ponovitev
							break;					//
						}							//
						Thread.Sleep(mojTimeout);		//
					}
					this.Cursor = Cursors.Default;
				}
			}
			else
			{
				vrstice = askStrings;
			}
			
			this.Text = mojSelektor.Substring(mojSelektor.LastIndexOf("\\")+1);
			if(this.Text.Contains("\t"))
			{
				this.Text = this.Text.Substring(0, this.Text.IndexOf("\t"));
			}
			
			// --------- Tu se začne procesiranje ASK obrazca -------------
			
			int razmik = 22;
			int comp = this.Controls.Count;
			int firstcomp = this.Controls.Count;
			int i = 1;
			foreach(string vrstica in vrstice)
			{
				if(vrstica.StartsWith(" Ask:"))
				{
					Label tl1 = new Label();
					tl1.Width =200;
					tl1.Height = 20;
					tl1.Left = 10;
					tl1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tl1.Text = vrstica.Substring(6,vrstica.IndexOf("\t")-6);
					}
					else
					{
						tl1.Text = vrstica.Substring(6);
					}
					this.Controls.Add(tl1);
				//	i++;
					comp++;
					TextBox tb1 = new TextBox();
					tb1.Name = "Ask";
					tb1.Width =200;
					tb1.Height = 20;
					tb1.Left = 210;
					tb1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tb1.Text = vrstica.Substring(vrstica.IndexOf("\t")+1);
					}
					//tb1.Text = vrstica.Substring(6);
					this.Controls.Add(tb1);
					i++;
					comp++;
				}
				if(vrstica.StartsWith(" AskP:"))
				{
					Label tl1 = new Label();
					tl1.Width =200;
					tl1.Height = 20;
					tl1.Left = 10;
					tl1.Top = (razmik*i)+10;
					tl1.Text = vrstica.Replace(" AskP:", string.Empty);
					this.Controls.Add(tl1);
					
					TextBox tb1 = new TextBox();
					tb1.Name = "AskP";
					tb1.Width =200;
					tb1.PasswordChar = '*';
					tb1.Height = 20;
					tb1.Left = 210;
					tb1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tb1.Text = vrstica.Substring(vrstica.IndexOf("\t")+1);
					}
					this.Controls.Add(tb1);
					i++;
					comp++;
				}
				if(vrstica.StartsWith(" Note:"))
				{
					Label tb1 = new Label();
					tb1.Width =600;
					tb1.Height = 20;
					tb1.Left = 10;
					tb1.Top = (razmik*i)+10;
					tb1.Text = vrstica.Replace(" Note:", string.Empty);
					this.Controls.Add(tb1);
					i++;
					comp++;
				}
				if(vrstica.StartsWith(" AskL:"))
				{
					Label tl1 = new Label();
					tl1.Width =600;
					tl1.Height = 20;
					tl1.Left = 10;
					tl1.Top = (razmik*i)+10;					
					tl1.Text = vrstica.Replace(" AskL:", string.Empty);
					this.Controls.Add(tl1);
					i++;
					
					TextBox tb1 = new TextBox();
					tb1.Name = "AskL";
					tb1.Multiline = true;
					tb1.Width =600;
					tb1.Height = 60;
					tb1.Left = 10;
					tb1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tb1.Text = vrstica.Substring(6,vrstica.IndexOf("\t")-6);
					}
//					else
//					{
//						tb1.Text = vrstica.Replace(" AskL:", string.Empty).TrimStart();
//					}
					tb1.ScrollBars = ScrollBars.Vertical;
					this.Controls.Add(tb1);
					i=i+3;
					comp++;
				}
				if(vrstica.StartsWith(" Select:"))
				{
					CheckBox tb1 = new CheckBox();
					tb1.Width =600;
					tb1.Height = 20;
					tb1.Left = 10;
					tb1.Top = (razmik*i)+10;
					if(vrstica.Contains(":"))
					{
						if(vrstica.EndsWith(":1"))
						{
							tb1.CheckState = CheckState.Checked;
							tb1.Text = vrstica.Replace(":1", string.Empty).Substring(8);
						}
						else if(vrstica.EndsWith(":0"))
						{
							tb1.Text = vrstica.Replace(":0", string.Empty).Substring(8);
						}
						else
						{
							tb1.Text = vrstica.Replace(" Select:", string.Empty);
						}
					}
					//tb1.Text = vrstica.Substring(9);
					this.Controls.Add(tb1);
					i++;
					comp++;
				}
				if(vrstica.StartsWith(" Choose:"))
				{
					GroupBox gb = new GroupBox();
					gb.Text = vrstica.Substring(8,vrstica.IndexOf("\t")-8);
					gb.Width = 600;
					gb.Height = 40;
					gb.Left = 10;
					gb.Top = (razmik*i)+10;
					this.Controls.Add(gb);
					i=i+2;
					comp++;
					List<string> radioItems = new List<string>();
					string testString = vrstica;
					testString = testString.Substring(testString.IndexOf("\t"));
					testString = testString.Trim();
					while(testString.LastIndexOf("\t") != -1)
					{
						radioItems.Add(testString.Substring(0, testString.IndexOf("\t")));
						testString = testString.Substring(testString.IndexOf("\t"));
						testString = testString.Trim();
					}
					if(testString != string.Empty)
					{
						radioItems.Add(testString.Trim());
					}
					int j = 0;	// število radioitems-ov
					int k = 0;  // števec - vsaka vrstica = tri radio items
					int l = 1; 	// vrstice
					foreach(string radioItem in radioItems)
					{
						//MessageBox.Show("+"+radioItem+"+");
						RadioButton tb1 = new RadioButton();
						tb1.Width =190;
						tb1.Height = 20;
						
						if(k == 3)
						{
							l++;
							k=0;
							j=0;
							i++;
						}
						tb1.Left = (190*j)+10;
						tb1.Top = (l*20)-5;
						tb1.Text = radioItem;
						gb.Controls.Add(tb1);
						if(l>0)
						{
							gb.Height = 20 + (l*20);
						}
						if(tb1.Parent.Controls.Count == 1) tb1.Checked = true;
						//this.Controls.Add(tb1);
						j++;
						k++;
						comp++;
					}
					//gb.Controls[0].Select();
				}
				if(vrstica.StartsWith(" AskF:"))
				{
					Label tl1 = new Label();
					tl1.Width =200;
					tl1.Height = 20;
					tl1.Left = 10;
					tl1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tl1.Text = vrstica.Substring(6,vrstica.IndexOf("\t")-6);
					}
					else
					{
						tl1.Text = vrstica.Replace(" AskF:", string.Empty);
					}
					this.Controls.Add(tl1);
					
					TextBox tb1 = new TextBox();
					tb1.Name = "AskF";
					tb1.Width =200;
					tb1.Height = 20;
					tb1.Left = 210;
					tb1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tb1.Text = vrstica.Substring(vrstica.IndexOf("\t")+1);
					}
					this.Controls.Add(tb1);
					comp++;
					Button tb2 = new Button();
					tb2.Width =100;
					tb2.Height = 20;
					tb2.Left = 410;
					tb2.Top = (razmik*i)+10;
					tb2.Text = "Select";
					tb2.Click += new EventHandler(onClickButtonSave);
					this.Controls.Add(tb2);
					i++;
					comp++;
				}
				if(vrstica.StartsWith(" ChooseF:"))
				{
					Label tl1 = new Label();
					tl1.Width =200;
					tl1.Height = 20;
					tl1.Left = 10;
					tl1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tl1.Text = vrstica.Substring(9,vrstica.IndexOf("\t")-9);
					}
					else
					{
						tl1.Text = vrstica.Replace(" ChooseF:", string.Empty);
					}
					this.Controls.Add(tl1);
					
					TextBox tb1 = new TextBox();
					tb1.Name = "ChooseF";
					tb1.Width =200;
					tb1.Height = 20;
					tb1.Left = 210;
					tb1.Top = (razmik*i)+10;
					if(vrstica.Contains("\t"))
					{
						tb1.Text = vrstica.Substring(vrstica.IndexOf("\t")+1);
					}
					this.Controls.Add(tb1);
					comp++;
					Button tb2 = new Button();
					tb2.Width =100;
					tb2.Height = 20;
					tb2.Left = 410;
					tb2.Top = (razmik*i)+10;
					tb2.Text = "Select";
					tb2.Click += new EventHandler(onClickButtonSelect);
					this.Controls.Add(tb2);
					i++;
					comp++;
				}
			}
			Button tb3 = new Button();
			tb3.Width =100;
			//tb3.Height = 20;
			tb3.Left = 160;
			tb3.Top = (razmik*i)+50;
			tb3.Text = "Send";
			tb3.DialogResult = DialogResult.OK;
			tb3.Click += new EventHandler(onClickButtonSend);
			this.Controls.Add(tb3);
			//i++;
			comp++;
			Button tb4 = new Button();
			tb4.Width =100;
			//tb3.Height = 20;
			tb4.Left = 360;
			tb4.Top = (razmik*i)+50;
			tb4.Text = "Cancel";
			tb4.DialogResult = DialogResult.Cancel;
			tb4.Click += new EventHandler(onClickButtonCancel);
			this.Controls.Add(tb4);
			i++;
			comp++;
			Label tl3 = new Label();
			tl3.Width =100;
			//tb3.Height = 20;
			tl3.Left = 110;
			tl3.Top = (razmik*i)+50;
			tl3.Text = "";
			this.Controls.Add(tl3);
			i++;
			comp++;
		}
		
		void onClickButtonSelect(object sender, EventArgs e)
		{
			for(int z = 0; z < this.Controls.Count; z++)
			{
				if((this.Controls[z].ContainsFocus) && (openFileDialog.ShowDialog() == DialogResult.OK))
				{
					this.Controls[z-1].Text = openFileDialog.FileName;
				}
			}
		}
		
		void onClickButtonSave(object sender, EventArgs e)
		{
			for(int z = 0; z < this.Controls.Count; z++)
			{
				if((this.Controls[z].ContainsFocus) && (saveFileDialog.ShowDialog() == DialogResult.OK))
				{
					this.Controls[z-1].Text = saveFileDialog.FileName;
				}
			}
		}
		
		void onClickButtonCancel(object sender, EventArgs e)
		{
			Close();
		}
		
		void onClickButtonSend(object sender, EventArgs e)
		{
			this.Cursor = Cursors.WaitCursor;
			List<String> odgovor = new List<string>();
			string sTemp = "";
			string sControl = "";
			string sText = "";
			for(int z = 0; z < this.Controls.Count; z++)
			{
				//MessageBox.Show(this.Controls[z].Name);
				sTemp = this.Controls[z].ToString().Replace("System.Windows.Forms.", string.Empty);
				sControl = sTemp.Substring(0, sTemp.IndexOf(","));
				sText = this.Controls[z].Text; //sTemp.Substring(sTemp.IndexOf(",")+2);
				if(sControl.ToLower() == "textbox")
				{
					if(this.Controls[z].Name == "AskL")
					{
						if(sText.Contains("\n"))
						{
							char[] separator = {'\n'};
							string[] test = this.Controls[z].Text.Split(separator);
							odgovor.Add(test.Length.ToString());
							foreach(string vrstica in test)
							{
								odgovor.Add(vrstica);
							}
						}
						else
						{
							odgovor.Add("1");
							odgovor.Add(sText);//.Substring(6));
						}
					}
					else if(this.Controls[z].Name == "ChooseF")
					{
						odgovor.Add("UuPpLlOoAaDd::"+this.Controls[z].Text);
					}
					else
					{
						odgovor.Add(sText); //.Substring(6));
					}
				}
				if(sControl.ToLower() == "checkbox")
				{
					//MessageBox.Show(this.Controls[z].ToString());
					odgovor.Add(this.Controls[z].ToString().Replace("System.Windows.Forms.CheckBox, CheckState: ", string.Empty));
					//odgovor.Add(sText.Replace("CheckState: ", string.Empty));
				}
				if(sControl == "GroupBox")
				{
					for(int j = 0; j < this.Controls[z].Controls.Count; j++)
					{
						if(this.Controls[z].Controls[j].ToString() == "System.Windows.Forms.RadioButton, Checked: True")
						{
							odgovor.Add(this.Controls[z].Controls[j].Text);
						}
					}
				}
				
			}
			
			bool uploading = false;
			//Stream SS = new FileStream("output.txt", FileMode.Append);
			//BinaryWriter SW = new BinaryWriter(SS);
			
			List<byte> ByteList = new List<byte>();
			foreach(string vrstica in odgovor)
			{
				if(vrstica.StartsWith("UuPpLlOoAaDd::"))
				{
					uploading = true;
					string imeDatoteke = vrstica.Replace("UuPpLlOoAaDd::", string.Empty);
					imeDatoteke = imeDatoteke.Trim();
					if(imeDatoteke != string.Empty)
					{
						FileInfo FI = new FileInfo(imeDatoteke);
						if(FI.Exists)
						{
							Stream BS = new FileStream(FI.FullName, FileMode.Open);
							BinaryReader SR = new BinaryReader(BS);
							
							if(FI.Exists)
							{
								//SR = new BinaryReader(SS1);
								byte[] c = new byte[FI.Length];
								SR.Read(c, 0, c.Length);
								
								foreach(byte b in c)
								{
									ByteList.Add(b);
								}
							}
						}						
					}					
				}
				else
				{
					//else SW.WriteLine(vrstica);
					char[] ch = new char[vrstica.Length];
					ch = vrstica.ToCharArray();
					foreach(byte test in Encoding.UTF8.GetBytes(vrstica.ToCharArray()))
					{
						ByteList.Add(test);
					}
					ByteList.Add(13); //cr
					ByteList.Add(10); //lf
				}				
			}
			try
			{
				using (TcpClient client = new TcpClient (mojStreznik, Convert.ToInt32(mojaVrata)))
				using (NetworkStream n = client.GetStream())
				{
					//MessageBox.Show(mojSelektor);
					List<byte> codgovor = new List<byte>();
					//SendCommand (n, mojSelektor+"\t$\t1");
					foreach(char b in (mojSelektor+"\t$\t1\r\n").ToCharArray())
					{
						codgovor.Add((byte)b);
					}
					
					
					string glava;
					if(uploading)
					{
						glava= "+"+ByteList.Count.ToString()+"\r\n";
						foreach(byte b in Encoding.UTF8.GetBytes(glava.ToCharArray()))
						{
							codgovor.Add(b);
						}
					}
					else
					{
						glava = "+-1\r\n";
						foreach(char b in (glava.ToCharArray()))
						{
							codgovor.Add((byte)b);
						}
					}
					
					
					//char[] cglava = glava.ToCharArray();
					//SendResponse(n, Encoding.UTF8.GetBytes(glava));
					//SendResponse(n, Encoding.ASCII.GetBytes(glava));
					//foreach(byte b in ByteList)
					//{
					//SendResponse(n, ByteList.ToArray());
					foreach(byte znak in ByteList)
					{
						codgovor.Add(znak);
					}
					
					//}
					string noga = ".\r\n";
					char[] cnoga = noga.ToCharArray();
					
					if(uploading == false)
					{
						//SendResponse(n, Encoding.ASCII.GetBytes(noga));
						//SendResponse(n, Encoding.UTF8.GetBytes(noga));
						foreach(char b in (noga.ToCharArray()))
						{
							codgovor.Add((byte)b);
						}
					}
					//SendResponse(n, Encoding.ASCII.GetBytes(codgovor.ToArray()));
					
					
					
					SendResponse(n, codgovor.ToArray());
					
					List<String> vrstice = new List<string>();
					
					
					int i = 0;
					while(vrstice.Count == 0)		//
					{								// večkratna ponovitev če večkrat ne dobimo nič...
						i++;
						if(n.DataAvailable == false)
						{
							Thread.Sleep(mojTimeout*3);
						}
						while (n.DataAvailable)
						{
							string line = ReadLine (n);
							vrstice.Add(line);

							if (n.DataAvailable == false) Thread.Sleep(mojTimeout);
						}
						if((i == 5) || (vrstice.Count != 0))					// poskusimo petkrat
						{							// to je za to, da nimamo večkratnik ponovitev
							break;					//
						}							//
						Thread.Sleep(mojTimeout);		//
					}
					rezultat = vrstice;
					//MessageBox.Show(rezultat[0]);
					//SW.Flush();
					//SW.Close();
					
				}
			}
			catch(Exception ex)
			{
				MessageBox.Show("Error in comunication with server:\n"+ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			this.Cursor = Cursors.Default;
			Close();
		}			
		
		void AskHelpRequested(object sender, HelpEventArgs hlpevent)
		{
			Help.ShowHelp(this, Application.ExecutablePath.Substring(0, Application.ExecutablePath.LastIndexOf("\\"))+"\\Help\\gopher.chm", "html\\ask-form.htm");
		}
	}
}
